package org.cn.cf.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import javax.security.cert.CertificateException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.endpoint.Message;
import net.jxta.id.IDFactory;
import net.jxta.impl.id.UUID.PipeID;
import net.jxta.impl.protocol.RdvConfigAdv;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.pipe.OutputPipe;
import net.jxta.pipe.PipeService;
import net.jxta.platform.NetworkConfigurator;
import net.jxta.platform.NetworkManager;
import net.jxta.protocol.ConfigParams;
import net.jxta.protocol.PeerAdvertisement;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.protocol.TransportAdvertisement;
import net.jxta.rendezvous.RendezVousService;


public class CFUtil {
	private static final Log log = LogFactory.getLog(CFUtil.class);

	public static NetworkManager startJxta(String fcName,String user,String psw){
		NetworkManager TheNetworkManager = null;
		NetworkConfigurator TheConfig = null;
		try {
            TheNetworkManager = new NetworkManager(
            		NetworkManager.ConfigMode.EDGE, fcName,new File(fcName+"/").toURI());//NetworkManager.ConfigMode.EDGE
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
        TheNetworkManager.setConfigPersistent(true);
        //TheNetworkManager.setUseDefaultSeeds(true);//动态使用

        //TheNetworkManager.

       
        try {
            TheConfig = TheNetworkManager.getConfigurator();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        if (TheConfig.exists()) {
            // We load it
            File LocalConfig = new File(TheConfig.getHome(), "PlatformConfig");
            try {
                TheConfig.load(LocalConfig.toURI());
                
                if(user!=null&&!"".equals(user))
                	TheConfig.setPrincipal(user);
                
                if(psw!=null&&!"".equals(psw))
                	TheConfig.setPassword(psw);
            } catch (IOException ex) {
            	log.error(ex.getMessage());
                return null;
            } catch (CertificateException ex) {
                // An issue with the existing peer certificate has been encountered
            	log.error(ex.getMessage());
                return null;
            }
        } else {

            TheConfig.setName(fcName);
            
            if(user!=null&&!"".equals(user))
            	TheConfig.setPrincipal(user);
            
            if(psw!=null&&!"".equals(psw))
            	TheConfig.setPassword(psw);
        }
        
        String ip = getLocalInfo(1);
        System.out.println("Myself ip is :"+ip);
    	if(isOutIp(ip)){
    		TheConfig.setUseMulticast(false);
        }else{
        	//TheConfig.setTcpPublicAddress("192.168.1.1:9701", true);
        	//TheConfig
        	TheConfig.setUseMulticast(true);
         	
        }
        
    	TheConfig.addRdvSeedingURI("tcp://220.162.244.95:9701");
    	TheConfig.addRdvSeedingURI("http://220.162.244.95:9700");

//    	TheConfig.addRelaySeedingURI("tcp://220.162.244.95:9701");
//    	TheConfig.addRelaySeedingURI("http://220.162.244.95:9700");
//    	
//    	TheConfig.addRdvSeedingURI("tcp://169.254.149.67:9701/tcp://58.61.63.185:9701");
//    	TheConfig.addRdvSeedingURI("http://169.254.149.67:9700/http://58.61.63.185:9700");
//    	
//    	TheConfig.addRelaySeedingURI("tcp://169.254.149.67:9701/tcp://58.61.63.185:9701");
//    	TheConfig.addRelaySeedingURI("http://169.254.149.67:9700/http://58.61.63.185:9700");
    	
        try {
        	TheConfig.save();
        	
        	ConfigParams cp = TheConfig.getPlatformConfig();
        	System.out.println("ConfigParams:\n"+cp.getDocument(MimeMediaType.XMLUTF8));
        	try{
        		StructuredDocument sd = cp.getServiceParam(IDFactory.fromURI(new URI("urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE0000000A05")));

        		//sd.
        		//System.out.println("TransportAdvertisement:\n"+cp.getServiceParam(IDFactory.fromURI(new URI("urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE0000000A05"))));
        	}catch(Exception e){
        		e.printStackTrace();
        	}
        } catch (IOException ex) {
            log.error(ex.getMessage());
            return null;
        }
        
        return TheNetworkManager;
	}
	
	//判断一个IP是否外部IP
	public static boolean isOutIp(String ip){
		if(ip==null||"".equals(ip))
			return true;
		String [] points = ip.split("\\.");
		if(points.length!=4)
			return true;
		
		if("10".equals(points[0])){
			return false;
		}else if("172".equals(points[0])){ 
			int point = Integer.parseInt(points[1]);
			if(point>15 && point<32)
				return false;
		}else if("192".equals(points[0])&&"168".equals(points[1])){
			return false;
		}
		return true;
	}
	
	/**
	 * type:
	 * 1 IP 
	 * 2 Name
	 * 3 IP--Name
	 * */
	public static String getLocalInfo(int type){
		InetAddress addr = null;
		try{
			addr = InetAddress.getLocalHost();
		}catch(Exception e){
			log.error(e.getMessage());
		}
		String ip = "127.0.0.1";
		String name = "unkown";
		if(addr!=null){
			ip = addr.getHostAddress().toString();//获得本机IP
			name = addr.getHostName().toString();//获得本机名称 
		}
		switch(type){
		case 1:return ip;
		case 2:return name;
		case 3:return ip+CFDefData.COMBO_SPSTR+name;
		default:return ip;
		}
		
	}

	
	public static String publishObject(DiscoveryService discoSvc,Object p2pObj){
		Advertisement adv = null;
		
		if(p2pObj instanceof Advertisement){
			adv = (Advertisement)p2pObj;
		}else{
			if(p2pObj instanceof PeerGroup){
				PeerGroup pg = (PeerGroup)p2pObj;
				adv = pg.getPeerGroupAdvertisement();
			}
		}
		
		log.info("即将发布的广告ID:"+adv.getID());
		log.info("即将发布的广告类型:"+adv.getAdvType());
		if(adv!=null){
			long lifetime = 160 * 2 * 1000L;
	        long expiration = 60 * 2 * 1000L;
			try {
				// publish this advertisement
				// (send out to other peers and rendezvous peer)
				System.out.println("local publish......");
				discoSvc.publish(adv,lifetime,expiration);
				System.out.println("remote publish......");
				discoSvc.remotePublish(adv,expiration);
				return null;
			} catch (Exception ex) {
				
				log.error(ex.getMessage());
				return ex.getMessage();
			}
		}else{
			
			log.error("广告发布广告错误,广告不能为Null");
			return "<<OBJ>>null";
		}
	}
	
	public static PipeAdvertisement crearePipeAdvertisement(String pipeIdStr,String pType,String pipName) {
        PipeID pipeID = null;

        try {
            pipeID = (PipeID) IDFactory.fromURI(new URI(pipeIdStr));
        } catch (URISyntaxException use) {
            use.printStackTrace();
            return null;
        }
        PipeAdvertisement advertisement = (PipeAdvertisement)
                AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());

        advertisement.setPipeID(pipeID);
        advertisement.setType(pType);
        advertisement.setName(pipName);
        
        log.info("广告已成功创建,名称:"+pipName+" 类型:"+pType+" 原始ID:"+pipeIdStr);
        
        return advertisement;
    }
	
	public static PipeAdvertisement crearePipeAdvertisement(PeerGroupID pg,String pType,String pipName) {
        PipeID pipeID = null;

        try {
            pipeID = (PipeID) IDFactory.newPipeID(pg);
        } catch (Exception use) {
            use.printStackTrace();
            return null;
        }
        PipeAdvertisement advertisement = (PipeAdvertisement)
        AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());
        
		advertisement.setPipeID(pipeID);
		advertisement.setType(pType);//PipeService.PropagateType
		advertisement.setName(pipName);

		//advertisement.getDocument(MimeMediaType.XMLUTF8).
		
		log.info("广告已成功创建,名称:"+pipName+" 类型:"+pType+" 新建ID:"+pipeID.toString());
		
		return advertisement;
    }

	
	public static boolean checkConditions(Map conditions,String name,String descr,String id){
		if(conditions==null) return true;
		
		String cond;
		 Object obj = conditions.get(CFDefData.NAME_STR);
		 if(obj!=null){
			 cond = obj.toString();
			 if(!cond.equalsIgnoreCase(name))
				 return false;
		 }
		 obj = conditions.get(CFDefData.DESCRIPTION_STR);
		 if(obj!=null){
			 cond = obj.toString();
			 if(descr.toUpperCase().indexOf(cond.toUpperCase())==-1)
				 return false;
		 }
		 
		 obj = conditions.get(CFDefData.ID_STR);
		 if(obj!=null){
			 cond = obj.toString();
			 if(!cond.equalsIgnoreCase(id))
				 return false;
		 }
		return true;
	}



	
	public static Advertisement loadAdvertisement(String fileURL){
		Advertisement adv = null;
		InputStream in = null;
		try{
			in = new FileInputStream(fileURL);
			adv = AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8, in);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try{
				if(in!=null)
					in.close();
			}catch(Exception e){}
		}
		return adv;
	}

}



















